package com.freewater.cargotracker.domain.model.voyage;

import com.freewater.cargotracker.domain.model.location.Location;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.EqualsBuilder;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Objects;

/**
 * 航线调度好的航程中的一段
 */
public class CarrierMovement implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;
    private Location departureLocation;
    private LocalDateTime departureTime;
    private Location arrivalLocation;
    private LocalDateTime arrivalTime;

    public CarrierMovement(Location departureLocation,
                           Location arrivalLocation,
                           LocalDateTime departureTime,
                           LocalDateTime arrivalTime) {
        Validate.notNull(departureLocation, "Departure location is required");
        Validate.notNull(arrivalLocation, "Arrival location is required");
        Validate.notNull(departureTime, "Departure time is required");
        Validate.notNull(arrivalTime, "Arrival time is required");

        this.departureLocation = departureLocation;
        this.arrivalLocation = arrivalLocation;
        this.departureTime = departureTime;
        this.arrivalTime = arrivalTime;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Location getDepartureLocation() {
        return departureLocation;
    }

    public void setDepartureLocation(Location departureLocation) {
        Validate.notNull(departureLocation, "Departure location is required");
        this.departureLocation = departureLocation;
    }

    public LocalDateTime getDepartureTime() {
        return departureTime;
    }

    public Location getArrivalLocation() {
        return arrivalLocation;
    }

    public void setArrivalLocation(Location arrivalLocation) {
        Validate.notNull(arrivalLocation, "Arrival location is required");
        this.arrivalLocation = arrivalLocation;
    }

    public LocalDateTime getArrivalTime() {
        return arrivalTime;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof CarrierMovement)) return false;
        CarrierMovement that = (CarrierMovement) o;
        return sameValueAs(that);
    }

    private boolean sameValueAs(CarrierMovement other) {
        return other != null
                && new EqualsBuilder()
                .append(departureLocation, other.departureLocation)
                .append(departureTime, other.departureTime)
                .append(arrivalLocation, other.arrivalLocation)
                .append(arrivalTime, other.arrivalTime)
                .isEquals();
    }

    @Override
    public int hashCode() {
        return Objects.hash(departureLocation, departureTime,
                arrivalLocation, arrivalTime);
    }
}
